const express = require('express')
const multiparty = require('connect-multiparty')
const path = require('path')
const fse = require('fs-extra')
const bodyParser = require("body-parser")

const app = express()
const multipartMiddleware = multiparty()
const parserBodyMiddleware = bodyParser.json()

app.listen(3000,() => {
    console.log('服务已开启。。。')
})

//设置允许fetch跨域中间件
const corsMiddleware = (req, res, next) => {
    res.set('Access-Control-Allow-Origin', '*')
    res.set('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
    res.set('Access-Control-Allow-Headers', 'X-Requested-With,content-type')
    res.set('Access-Control-Allow-Credentials', true)
    next()
}

app.use(parserBodyMiddleware)
app.use(corsMiddleware)

//上传的文件都存储在这个文件夹中
const uploadPath = path.resolve(__dirname, 'uploads')
//上传文件
app.post('/upload', multipartMiddleware, (req,res) => {
    const {fileHash,chunkHash} = req.body

    //用filehash命名临时文件夹，存储上传的分片文件
    const dirPath = path.resolve(uploadPath,fileHash)
    if(!fse.existsSync(dirPath)){
        fse.mkdirSync(dirPath)
    }
    //如果临时文件夹中没有分片，就将分片移入文件夹里
    const chunkPath = path.resolve(dirPath,chunkHash)
    if(!fse.existsSync(chunkPath)){
        fse.moveSync(req.files.file.path,chunkPath)
    }

    res.json({
        code:200,
        msg:'上传成功',
        data:null
    })
})

//校验文件是否存在
app.post('/validate',(req, res) => {
    const { fileHash, fileName } = req.body

    //文件路径
    const filePath = path.resolve(uploadPath, fileHash + path.extname(fileName))

    const isExist = fse.existsSync(filePath)

    //找出已经上传的分片
    const chunksPath = path.resolve(uploadPath, fileHash)
    let existsFiles = []
    if(fse.existsSync(chunksPath)){
        const chunks = fse.readdirSync(chunksPath)
        existsFiles = chunks
    }

    res.json({
        code:200,
        msg:'',
        data:{
            isExist,
            existsFiles
        }
    })
})

//合并临时文件
app.post('/merge',async (req,res) => {
    const {fileHash,fileName} = req.body

    //文件路径
    const filePath = path.resolve(uploadPath,fileHash + path.extname(fileName))
    //临时文件夹
    const chunkDir = path.resolve(uploadPath,fileHash)

    const chunks = fse.readdirSync(chunkDir)
    //按下标升序
    chunks.sort((a,b) => a.split('-')[1] - b.split('-')[1])
    const tools = chunks.map(chunk => new Promise((resolve) => {
        const file = fse.readFileSync(path.resolve(chunkDir, chunk))
        fse.appendFileSync(filePath, file)
        fse.unlinkSync(path.resolve(chunkDir, chunk))
        resolve()
    }))
    await Promise.all(tools)

    fse.removeSync(chunkDir)
    res.json({
        code:200,
        msg:'合并成功',
        data:null
    })
})